#include "invertedindex.h"

using namespace invertedindex;

InvertedIndex::InvertedIndex():
	treeHandler("conf/"),
	streamHandler()
{
	
}

InvertedIndex::~InvertedIndex(){
}

bool InvertedIndex::insert(const InvertedIndexData& invIdxData){
	bool ret = false;

	//Creo wordContainer
	std::pair<unsigned int,char*> wr=invIdxData.getWord();
	WordContainer wc(wr.first,wr.second, invIdxData.getWordId());
	
	if(!treeHandler.getWord(wc)){
		//Pregunto si invIdxData contiene documentos
		if(invIdxData.getDocumentsCount()>0){
			//Si tengo docs inserto en blockFile los documentos
			if(streamHandler.insertDocuments(wc, invIdxData.dc)){
				//Inserto en bstree la palabra
				if(treeHandler.insertWord(wc))
					ret=true;
			}
		}
		else{
			//Si no tengo documentos solo guardo palabras
			if(treeHandler.insertWord(wc))
				ret=true;
		}
	}
	else{
		std::cout<<"La palabra ya existia"<<std::endl;
		invIdxData.toOstream(std::cout);
	}
	delete [] wr.second;
	return ret; 
}

bool InvertedIndex::update(const InvertedIndexData& invIdxData){
	bool ret=false;
	//Creo wordContainer
	std::pair<unsigned int,char*> wr=invIdxData.getWord();
	WordContainer wc(wr.first,wr.second, invIdxData.getWordId());
	//busco en bs
	if(treeHandler.getWord(wc)){
		BlockPointer* bp1 = wc.getBP();
		//si tiene documentos hago update de blockFile
		if(bp1!=NULL){
			if(streamHandler.updateDocuments(wc, invIdxData.dc)){
				//si cambio block pointer actualizo bs
				BlockPointer* bp2 = wc.getBP();
				if(bp2->compare(*bp1)!=0){
					if(treeHandler.modifyWordBlockPointer(wc))
						ret=true;
				}
				else ret=true;
				delete bp2;
			}
			delete bp1;
		}
		else{
			//Si no tengo docs inserto en blockFile los documentos
			if(streamHandler.insertDocuments(wc, invIdxData.dc)){
				//Inserto en bstree el nuevo block pointer
				if(treeHandler.modifyWordBlockPointer(wc))
					ret=true;
			}
		}
	}
	delete [] wr.second;
	return ret;
}

bool InvertedIndex::search(InvertedIndexData& invIdxData){
	bool ret=false;
	//Creo wordContainer
	std::pair<unsigned int,char*> wr=invIdxData.getWord();
	WordContainer wc(wr.first,wr.second, invIdxData.getWordId());
	//Busco en bs
	if(treeHandler.getWord(wc)){

		BlockPointer* bp1 = wc.getBP();
		if(bp1!=NULL){
			//si wc tiene documentos busco en blockFile
			if(streamHandler.searchDocuments(wc, invIdxData.dc)){
				ret=true;
				invIdxData.wrd.setWordId(wc.getWordId());
			}
			delete bp1;
		}
		else{
			ret=true;
			invIdxData.wrd.setWordId(wc.getWordId());
		}
	}
	delete [] wr.second;
	return ret;
}

bool InvertedIndex::exist(InvertedIndexData& invIdxData){
	bool ret=false;
	//Creo wordContainer
	std::pair<unsigned int,char*> wr=invIdxData.getWord();
	WordContainer wc(wr.first,wr.second, invIdxData.getWordId());
	//Busco en bs
	if(treeHandler.getWord(wc)){
		ret=true;
		invIdxData.wrd.setWordId(wc.getWordId());
	}
	delete [] wr.second;
	return ret; 
}

void InvertedIndex::printTreeBlock(std::ostream& out, unsigned int offset){
	treeHandler.printTreeBlock(out, offset);
}



